package edu.jhu.cs.oose.scheduleit.backingbeans;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;

import edu.jhu.cs.oose.scheduleit.services.GroupService;
import edu.jhu.cs.oose.scheduleit.services.ScheduleService;
import edu.jhu.cs.oose.scheduleit.services.impl.DataBaseException;
import edu.jhu.cs.oose.scheduleit.util.Comparator;
import edu.jhu.cs.oose.scheduleit.util.Filter;
import edu.jhu.cs.oose.scheduleit.util.GroupAttributeKind;
import edu.jhu.cs.oose.scheduleit.util.ScheduleAttributeKind;
import edu.jhu.cs.oose.scheduleit.vo.Group;
import edu.jhu.cs.oose.scheduleit.vo.Schedule;

/**
 * the backing bean used to deal with all functions related to 'Search' feature.
 * @author oose_group2
 *
 */
public class SearchBackingBean {
	/**
	 * save the selected metric used to search schedule.
	 */
	private String scheduleSelectedMetric = "Topic";
	/**
	 * render the schedule metric selection
	 */
	private List<SelectItem> scheduleMetrics = new ArrayList<SelectItem>();
	/**
	 * save the selected metric used to search group
	 */
	private String groupSelectedMetric = "ID";
	/**
	 * render the group metric selection.
	 */
	private List<SelectItem> groupMetrics = new ArrayList<SelectItem>();
	/**
	 * getter of scheduleSelectedMetric
	 * @return
	 */
	public String getScheduleSelectedMetric() {
		return scheduleSelectedMetric;
	}
	/**
	 * setter of scheduleSelectedMetric
	 * @param scheduleSelectedMetric
	 */
	public void setScheduleSelectedMetric(String scheduleSelectedMetric) {
		this.scheduleSelectedMetric = scheduleSelectedMetric;
	}
	/**
	 * getter of scheduleMetrics
	 * @return
	 */
	public List<SelectItem> getScheduleMetrics() {
		return scheduleMetrics;
	}
	/**
	 * setter of scheduleMetrics
	 * @param scheduleMetrics
	 */
	public void setScheduleMetrics(List<SelectItem> scheduleMetrics) {
		this.scheduleMetrics = scheduleMetrics;
	}
	/**
	 * getter of groupSelectedMetric.
	 * @return
	 */
	public String getGroupSelectedMetric() {
		return groupSelectedMetric;
	}
	/**
	 * setter of groupSelectedMetric
	 * @param groupSelectedMetric
	 */
	public void setGroupSelectedMetric(String groupSelectedMetric) {
		this.groupSelectedMetric = groupSelectedMetric;
	}
	/**
	 * getter of groupMetric
	 * @return
	 */
	public List<SelectItem> getGroupMetrics() {
		return groupMetrics;
	}
	/**
	 * setter of groupMetric
	 * @param groupMetrics
	 */
	public void setGroupMetrics(List<SelectItem> groupMetrics) {
		this.groupMetrics = groupMetrics;
	}
	/**
	 * save schedule search result
	 */
	private List<Schedule> schedules = null;
	/**
	 * save the schedule search key word
	 */
	private String scheduleKeywords;
	/**
	 * save the group search key word
	 */
	private String groupKeywords;
	/**
	 * reference of scheduleService
	 */
	private ScheduleService scheduleService;
	/**
	 * reference of groupService
	 */
	private GroupService groupService;
	/**
	 * save the group search result
	 */
	private List<Group> groups = null;
	/**
	 * constructor of SearchBackingBean
	 */
	public SearchBackingBean() {
		this.scheduleMetrics.add(new SelectItem("Topic"));
		this.scheduleMetrics.add(new SelectItem("Tags"));
		this.scheduleMetrics.add(new SelectItem("Both"));
		this.groupMetrics.add(new SelectItem("ID"));
		this.groupMetrics.add(new SelectItem("Topic"));
		this.groupMetrics.add(new SelectItem("Tags"));
		this.groupMetrics.add(new SelectItem("All"));
	}
	/**
	 * setter of schedules
	 * @param schedules
	 */
	public void setSchedules(List<Schedule> schedules) {
		this.schedules = schedules;
	}
	/**
	 * getter of schedules
	 * @return
	 */
	public List<Schedule> getSchedules() {
		return this.schedules;
	}

	/**
	 * getter of scheduleService
	 * @return
	 */
	public ScheduleService getScheduleService() {
		return scheduleService;
	}
	/**
	 * setter of scheduleService
	 * @param scheduleService
	 */
	public void setScheduleService(ScheduleService scheduleService) {
		this.scheduleService = scheduleService;
	}
	/**
	 * method to respond to search schedule command
	 * @return JSF direction string
	 */
	public String searchSchedules() {
		try {
			if (scheduleKeywords == null)
				this.schedules = null;
			else {
				List<Filter> filters = new LinkedList<Filter>();
				if (scheduleSelectedMetric.equals("Tags")) {
					List<String> tags = new LinkedList<String>();
					String[] tmpTags = scheduleKeywords.split(" ");
					for (String s : tmpTags) {
						tags.add(s);
					}
					filters.add(new Filter(ScheduleAttributeKind.tags,Comparator.LIKE,
							tags));
				} else if (scheduleSelectedMetric.equals("Topic")) {
					filters.add(new Filter(ScheduleAttributeKind.topic, Comparator.LIKE,
							scheduleKeywords));
				} else if (scheduleSelectedMetric.equals("Topic")
						|| scheduleSelectedMetric.equals("Both")) {
					List<String> tags = new LinkedList<String>();
					String[] tmpTags = scheduleKeywords.split(" ");
					for (String s : tmpTags) {
						tags.add(s);
					}
					filters.add(new Filter(ScheduleAttributeKind.tags,Comparator.LIKE,
							tags));
					filters.add(new Filter(ScheduleAttributeKind.topic, Comparator.LIKE,
							scheduleKeywords));
				}
				this.schedules = this.scheduleService
				.getSchedule(filters, 0, 0);
			}
		} catch (DataBaseException e) {
			e.printStackTrace();
		}
		return "searchSchedules";
	}
	/**
	 * setter of groupService
	 * @param groupService
	 */
	public void setGroupService(GroupService groupService) {
		this.groupService = groupService;
	}
	/**
	 * getter of groupService
	 * @return
	 */
	public GroupService getGroupService() {
		return groupService;
	}
	/**
	 * method to respond to search group command
	 * @return JSF direction string
	 */
	public String searchGroups() {
		try {
			if (groupKeywords == null)
				this.groups = null;
			else {
				List<Filter> filters = new LinkedList<Filter>();
				if (groupSelectedMetric.equals("Tags")) {
					List<String> tags = new LinkedList<String>();
					String[] tmpTags = groupKeywords.split(" ");
					for (String s : tmpTags) {
						tags.add(s);
					}
					filters.add(new Filter(GroupAttributeKind.tags,Comparator.LIKE, tags));
				} else if (groupSelectedMetric.equals("Topic")) {
					filters.add(new Filter(GroupAttributeKind.topic,Comparator.LIKE, groupKeywords));					
				} else if (groupSelectedMetric.equals("ID")) {					
					filters.add(new Filter(GroupAttributeKind.id, Comparator.EQ, Integer.parseInt(groupKeywords)));
				} else if (groupSelectedMetric.equals("All")){
					List<String> tags = new LinkedList<String>();
					String[] tmpTags = groupKeywords.split(" ");
					for (String s : tmpTags) {
						tags.add(s);
					}
					filters.add(new Filter(GroupAttributeKind.tags,Comparator.LIKE, tags));
					filters.add(new Filter(GroupAttributeKind.topic,Comparator.LIKE, groupKeywords,true));
					//filters.add(new Filter(GroupAttributeKind.id, Comparator.EQ, Integer.parseInt(groupKeywords)));
				}
				this.groups = this.groupService.getGroup(filters, 0, 0);
			}
		} catch (Exception e) {
			e.printStackTrace();
			this.groups = null;
		}
		return "searchGroups";
	}
	/**
	 * getter of scheduleKeywords
	 * @return
	 */
	public String getScheduleKeywords() {
		return scheduleKeywords;
	}
	/**
	 * setter of scheduleKeywords
	 * @param scheduleKeywords
	 */
	public void setScheduleKeywords(String scheduleKeywords) {
		this.scheduleKeywords = scheduleKeywords;
	}
	/**
	 * getter of groupKeywords
	 * @return
	 */
	public String getGroupKeywords() {
		return groupKeywords;
	}
	/**
	 * setter of groupKeywords
	 * @param groupKeywords
	 */
	public void setGroupKeywords(String groupKeywords) {
		this.groupKeywords = groupKeywords;
	}
	/**
	 * setter of groups
	 * @param groups
	 */
	public void setGroups(List<Group> groups) {
		this.groups = groups;
	}
	/**
	 * getter of groups
	 * @return
	 */
	public List<Group> getGroups() {
		return groups;
	}
	/**
	 * method respond to view result schedule command
	 * @return
	 */
	public String viewSchedule(){
		FacesContext context = FacesContext.getCurrentInstance();
		int scheduleid = Integer.parseInt(context.getExternalContext().getRequestParameterMap().get("scheduleId"));
		for(Schedule schedule:this.schedules){
			if(schedule.getId()==scheduleid){
				try {
					ScheduleBackingBean sbb = (ScheduleBackingBean)context.getExternalContext().getSessionMap().get("scheduleBackingBean");
					sbb.initCalendar(schedule, true);
					break;
				} catch (DataBaseException e) {
					return "viewSchedule";
				}
			}
		}
		return "viewSchedule";
	}
}
